#include "verification.h"
#include "func.h"
#include "transMsg.h"

int cmdShareInit(cmdShare_t* pCmdShare,const char* id,const char* token,const char* command){
    memset(pCmdShare,0,sizeof(cmdShare_t));
    memcpy(pCmdShare->id,id,strlen(id));
    memcpy(pCmdShare->token,token,strlen(token));
    memcpy(pCmdShare->command,command,strlen(command));
    return 0;
}

int generateId(const char* username,char* id){
    //每个Id,由前5位随机数+用户名组成
    char geneId[256] = {0};
    srand(time(NULL));
    char tmp[256] = {0};
    for(int idx =0; idx < 5; ++idx){
        int randnum = rand()%10;
        memset(tmp,0,sizeof(tmp));
        sprintf(tmp,"%s",geneId);
        memset(geneId,0,sizeof(geneId));
        sprintf(geneId,"%s%d",tmp,randnum);
    }
    memset(tmp,0,sizeof(tmp));
    sprintf(tmp,"%s",geneId);
    memset(geneId,0,sizeof(geneId));
    sprintf(geneId,"%s%s",tmp,username);
    memset(id,0,sizeof(geneId));
    memcpy(id,geneId,strlen(geneId));
    /* printf("geneId = %s\n",geneId); */
    return 0;
}

int getusername(const char* id,char* username){ //根据返回的id,获取username;
    memset(username,0,strlen(id)+1);
    memcpy(username,id+5,strlen(id)-5);
    return 0;
}

int getIdAndToken(const char* response,char* id,char* token){ //登录和注册时根据服务端的返回结果,获取id和token
    //切分响应
    char tmpResp[4096] = {0};
    memcpy(tmpResp,response,strlen(response));
    char* respId;
    char* respToken;
    respId = strtok_r(tmpResp," ",&respToken);
    memcpy(id,respId,strlen(respId)+1);
    memcpy(token,respToken,strlen(respToken)+1);
    return 0;
}    

int tokenVerify(int sockfd,const char* id,const char* token,const char* command){   //进行token验证
    //构建request请求,包括id,token,command
    char request[4096] = {0};
    sprintf(request,"%s %s %s",id,token,command);
    /* printf("request = %s\n",request); */
    train_t train;
    memset(&train,0,sizeof(train_t));
    train.length = strlen(request)+1;
    send(sockfd,&train.length,sizeof(train.length),0);
    memcpy(train.data,request,train.length);
    send(sockfd,train.data,train.length,0);
    /* printf("train.data = %s\n",train.data); */
    
    //接收回复
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,&train.data,train.length);
    if(memcmp(train.data,"0",sizeof("0"))==0){
        /* printf("token Verification Successful\n"); */
        return 0;
    }
    printf("token Verification failure\n");
    return -1;
}
int pwdAuth(int sockfd,cmdShare_t* pCmdShare){
    train_t train;
    //接收用户名和密码
    char username[256]={0};
    char password[256]={0};
    printf("Please enter your username:");
    scanf("%s",username);
    getchar();//接收最后的换行符;
    printf("Please enter your password:");
    scanf("%s",password);
    getchar();//接收最后的换行符

    //char username[256] = "test1";
    //char password[256] = "123456";

    //将用户名发送给服务端
    memset(&train,0,sizeof(train_t));
    train.length = strlen(username);
    memcpy(train.data,username,train.length);
    send(sockfd,&train.length,sizeof(train.length),0);
    send(sockfd,&train.data,train.length,0);
    //接收服务端返回的值
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    if(memcmp(train.data,"-1",strlen("0"))==0){
        //服务器端没有对应的用户
        printf("ERROR User not exists!\n");
        return -1;
    }
    //服务端有对应的用户，接收到盐值(salt)
    char salt[1024] = {0};
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    memcpy(salt,train.data,train.length);
    //printf("salt = %s\n",salt);
    //对salt和明文密码(password)加密,得到密文密码
    char* secret; 
    secret = crypt(password,salt);
    //将密文密码发送给服务端
    memset(&train,0,sizeof(train_t));
    train.length = strlen(secret);
    memcpy(train.data,secret,train.length);
    send(sockfd,&train.length,sizeof(train.length),0);
    send(sockfd,train.data,train.length,0);
    //接收登录是否成功
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    if(memcmp(train.data,"-1",train.length)==0){
        //密码验证失败
        printf("ERROR Incorrect username or password!\n");
        return -1;
    }
    //密码验证成功,接受id,token
    char respId[512] = {0};
    char respToken[1024] ={0};
    getIdAndToken(train.data,respId,respToken);
    /* printf("respId = %s,respToken = %s\n",respId,respToken); */
    memset(pCmdShare,0,sizeof(cmdShare_t));
    memcpy(pCmdShare->id,respId,strlen(respId));
    memcpy(pCmdShare->token,respToken,strlen(respToken));
    printf("Success!\n");
    return 0;
}

int userRegister(int sockfd,cmdShare_t* pCmdShare){
    train_t train;
    char username[256] = {0};
    char passWord[256] = {0};
    char rePassWord[256] = {0};

    //获取用户名
    printf("Please enter your username:");
    char ch;
    for(int i=0;(ch = getchar())!='\n';++i){
        username[i] = ch;
    }
    /* printf("username = %s\n",username); */
    //将用户名发送给用户端
    memset(&train,0,sizeof(train_t));
    train.length = strlen(username);
    memcpy(train.data,username,train.length);
    send(sockfd,&train.length,sizeof(train.length),0);
    send(sockfd,train.data,train.length,0);

    //接收是该用户名是否已存在
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    if(memcmp(train.data,"-1",train.length)==0){
        //该用户已经存在
        printf("This username is existance!\n");
        return -1;
    }

    //该用户名在服务器中不存在
    //获取密码
    printf("Please enter your password:");
    for(int i=0;(ch = getchar())!='\n';++i){
        passWord[i] = ch;
    }
    //再次获取密码
    printf("Please enter your password again:");
    for(int i=0;(ch = getchar())!='\n';++i){
        rePassWord[i] = ch;
    }
    printf("passWord =%s,rePassWord =%s\n",passWord,rePassWord);
    int isSame = 0;
    //判断两次输入的密码是否一致
    //通知服务器密码是否通过
    if(memcmp(passWord,rePassWord,sizeof(passWord))==0){
        isSame = 1;
        memset(&train,0,sizeof(train_t));
        train.length = strlen("0");
        memcpy(train.data,"0",train.length);
        send(sockfd,&train.length,sizeof(train.length),0);
        send(sockfd,train.data,train.length,0);
        /* printf("isSame = %d\n",isSame); */
    }
    else{
        isSame = 0;
        /* printf("isSame = %d\n",isSame); */
        memset(&train,0,sizeof(train_t));
        train.length = strlen("-1");
        memcpy(train.data,"-1",train.length);
        send(sockfd,&train.length,sizeof(train.length),0);
        send(sockfd,train.data,train.length,0);
        return -1;
    }


    //接收盐值
    char salt[1024] = {0};
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    memcpy(salt,train.data,train.length);
    //printf("salt = %s\n",salt);
    //对salt和明文密码(password)加密,得到密文密码
    char* secret; 
    secret = crypt(passWord,salt);
    //将密文密码发送给服务端
    memset(&train,0,sizeof(train_t));
    train.length = strlen(secret);
    memcpy(train.data,secret,train.length);
    send(sockfd,&train.length,sizeof(train.length),0);
    send(sockfd,train.data,train.length,0);
    //printf("train.length = %d\n,train.data = %s\n",train.length,train.data);

    //接收注册是否成功
    memset(&train,0,sizeof(train_t));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    //printf("train.length = %d,train.data = %s\n",train.length,train.data);
    if(memcmp(train.data,"-1",train.length)==0){
        //注册失败
        printf("Failed!\n");
        return -1;
    }
    //注册成功,接收id和token
    char respId[512] = {0};
    char respToken[1024] ={0};
    getIdAndToken(train.data,respId,respToken);
    /* printf("respId = %s,respToken = %s\n",respId,respToken); */
    memset(pCmdShare,0,sizeof(cmdShare_t));
    memcpy(pCmdShare->id,respId,strlen(respId));
    memcpy(pCmdShare->token,respToken,strlen(respToken));
    printf("Success!\n");
    return 0;
}
